package com.zebraphp.devtool.httpUtils.cookieJarPersistent;

import com.zebraphp.devtool.httpUtils.cookieJarPersistent.cache.CookieRunCacheInterfaceStandard;
import com.zebraphp.devtool.httpUtils.cookieJarPersistent.cache.CookieRunCacheUtil;
import com.zebraphp.devtool.httpUtils.cookieJarPersistent.storage.CookieStoreInterfaceStandard;
import com.zebraphp.devtool.httpUtils.cookieJarPersistent.storage.CookieStoreUtil;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;

public class PersistentCookieJar implements CookieJar {

    private CookieRunCacheInterfaceStandard mRunCacheUtil;//程序运行期间的cookie缓存
    private CookieStoreInterfaceStandard mStoreUtil;//持久化的cookie缓存

    public PersistentCookieJar(CookieRunCacheUtil cacheUtil, CookieStoreUtil storeUtil) {

        this.mRunCacheUtil = cacheUtil;
        this.mStoreUtil = storeUtil;

        this.mRunCacheUtil.saveCookies(mStoreUtil.getAllCookies());//把持久化的 cookie 添加到运行缓存中
    }

    /**
     * 保存来自服务器的 cookie 信息
     */
    @Override
    synchronized public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {

        mRunCacheUtil.saveCookies(cookies);//来自服务器设置的cookies 添加到 运行 缓存

        List<Cookie> persistentCookies = new ArrayList<>();

        for (Cookie cookie : cookies) {
//            if (cookie.persistent()) {//persistent ： True if 'expires' or 'max-age' is present.
                persistentCookies.add(cookie);
//            }
        }

        mStoreUtil.saveCookies(persistentCookies);//添加到 持久化 存储
    }

    /**
     * 根据url 在请求头 加入 cookie
     */
    @Override
    synchronized public List<Cookie> loadForRequest(HttpUrl url) {

        List<Cookie> cookiesToRemove = new ArrayList<>();//失效将要移除的cookie
        List<Cookie> validCookies = new ArrayList<>();//有效的cookie

        for (Iterator<Cookie> it = mRunCacheUtil.iterator(); it.hasNext(); ) {
            Cookie currentCookie = it.next();

            if (isCookieExpired(currentCookie)) {
                cookiesToRemove.add(currentCookie);//把cookie加入到要移除的集合中
                it.remove();

            } else if (currentCookie.matches(url)) {//如果 当前 cookie 是该url域名下的 加入到 有效cookie中
                validCookies.add(currentCookie);
            }
        }

        mStoreUtil.removeCookies(cookiesToRemove);//清除 持久化 中 失效的cookie

        return validCookies;//返回有效cookie
    }

    /**
     * cookie 是否超时
     */
    private static boolean isCookieExpired(Cookie cookie) {
        return cookie.expiresAt() < System.currentTimeMillis();
    }

    /**
     * 清除 session 中所有 对应的 cookies
     */
    synchronized public void clearCache() {
        mRunCacheUtil.clearCookies();
        mRunCacheUtil.saveCookies(mStoreUtil.getAllCookies());//从持久化存储中，加入一份cookie到cache 中
    }

    /**
     * 清除 cache 和 persistence 中的 所有 cookies
     */
    synchronized public void clearCacheAndStore() {
        mRunCacheUtil.clearCookies();
        mStoreUtil.clearCookies();
    }
}
